// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include <climits>
#include <cmath>
#include <cstddef>
#include <map>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "function_test_util.h"
#include "vec/columns/column.h"
#include "vec/columns/column_const.h"
#include "vec/columns/column_decimal.h"
#include "vec/columns/columns_number.h"
#include "vec/common/assert_cast.h"
#include "vec/core/column_numbers.h"
#include "vec/core/types.h"
#include "vec/data_types/data_type_decimal.h"
#include "vec/data_types/data_type_number.h"
#include "vec/functions/round.h"

/**
 This BE UT focus on enhancement of round based function, which enables them 
 to use column as scale argument. We test truncate/floor/ceil/round/round_bankers 
 together by moving test cases of function_truncate_test.cpp here.
*/

namespace doris::vectorized {
// {precision, scale} -> {input, scale_arg, expectation}
using DecimalTestDataSet =
        std::map<std::pair<int, int>, std::vector<std::tuple<Int128, int, Int128>>>;

// input, scale_arg, expectation
using FloatTestDataSet = std::vector<std::tuple<Float64, int, Float64>>;

using DecimalTruncateFunction = FunctionRounding<DecimalRoundTwoImpl<TruncateName>,
                                                 RoundingMode::Trunc, TieBreakingMode::Auto>;
using DecimalFloorFunction = FunctionRounding<DecimalRoundTwoImpl<FloorName>, RoundingMode::Floor,
                                              TieBreakingMode::Auto>;
using DecimalCeilFunction =
        FunctionRounding<DecimalRoundTwoImpl<CeilName>, RoundingMode::Ceil, TieBreakingMode::Auto>;
using DecimalRoundFunction = FunctionRounding<DecimalRoundTwoImpl<RoundName>, RoundingMode::Round,
                                              TieBreakingMode::Auto>;
using DecimalRoundBankersFunction = FunctionRounding<DecimalRoundTwoImpl<RoundBankersName>,
                                                     RoundingMode::Round, TieBreakingMode::Bankers>;

using FloatTruncateFunction = FunctionRounding<DoubleRoundTwoImpl<TruncateName>,
                                               RoundingMode::Trunc, TieBreakingMode::Auto>;
using FloatFloorFunction =
        FunctionRounding<DoubleRoundTwoImpl<FloorName>, RoundingMode::Floor, TieBreakingMode::Auto>;
using FloatCeilFunction =
        FunctionRounding<DoubleRoundTwoImpl<CeilName>, RoundingMode::Ceil, TieBreakingMode::Auto>;
using FloatRoundFunction =
        FunctionRounding<DoubleRoundTwoImpl<RoundName>, RoundingMode::Round, TieBreakingMode::Auto>;
using FloatRoundBankersFunction = FunctionRounding<DoubleRoundTwoImpl<RoundBankersName>,
                                                   RoundingMode::Round, TieBreakingMode::Bankers>;

// test cases for truncate and floor function of decimal32
const static DecimalTestDataSet trunc_floor_decimal32_cases = {
        {{1, 0},
         {
                 {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0}, {1, -5, 0},
                 {1, -4, 0},  {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 1},  {1, 1, 1},
                 {1, 2, 1},   {1, 3, 1},  {1, 4, 1},  {1, 5, 1},  {1, 6, 1},  {1, 7, 1},
                 {1, 8, 1},   {1, 9, 1},  {1, 10, 1},
         }},
        {{1, 1},
         {
                 {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0}, {1, -5, 0},
                 {1, -4, 0},  {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 0},  {1, 1, 1},
                 {1, 2, 1},   {1, 3, 1},  {1, 4, 1},  {1, 5, 1},  {1, 6, 1},  {1, 7, 1},
                 {1, 8, 1},   {1, 9, 1},  {1, 10, 1},
         }},
        {{2, 0},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 10},
                 {12, 0, 12},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 1},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 0},
                 {12, 0, 10},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 2},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 0},
                 {12, 0, 0},
                 {12, 1, 10},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{9, 0},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 100000000},
                 {123456789, -7, 120000000}, {123456789, -6, 123000000}, {123456789, -5, 123400000},
                 {123456789, -4, 123450000}, {123456789, -3, 123456000}, {123456789, -2, 123456700},
                 {123456789, -1, 123456780}, {123456789, 0, 123456789},  {123456789, 1, 123456789},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 1},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 100000000}, {123456789, -6, 120000000}, {123456789, -5, 123000000},
                 {123456789, -4, 123400000}, {123456789, -3, 123450000}, {123456789, -2, 123456000},
                 {123456789, -1, 123456700}, {123456789, 0, 123456780},  {123456789, 1, 123456789},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 2},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 100000000}, {123456789, -5, 120000000},
                 {123456789, -4, 123000000}, {123456789, -3, 123400000}, {123456789, -2, 123450000},
                 {123456789, -1, 123456000}, {123456789, 0, 123456700},  {123456789, 1, 123456780},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 3},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 100000000},
                 {123456789, -4, 120000000}, {123456789, -3, 123000000}, {123456789, -2, 123400000},
                 {123456789, -1, 123450000}, {123456789, 0, 123456000},  {123456789, 1, 123456700},
                 {123456789, 2, 123456780},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 4},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 100000000}, {123456789, -3, 120000000}, {123456789, -2, 123000000},
                 {123456789, -1, 123400000}, {123456789, 0, 123450000},  {123456789, 1, 123456000},
                 {123456789, 2, 123456700},  {123456789, 3, 123456780},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 5},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 100000000}, {123456789, -2, 120000000},
                 {123456789, -1, 123000000}, {123456789, 0, 123400000},  {123456789, 1, 123450000},
                 {123456789, 2, 123456000},  {123456789, 3, 123456700},  {123456789, 4, 123456780},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 6},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 0},        {123456789, -2, 100000000},
                 {123456789, -1, 120000000}, {123456789, 0, 123000000}, {123456789, 1, 123400000},
                 {123456789, 2, 123450000},  {123456789, 3, 123456000}, {123456789, 4, 123456700},
                 {123456789, 5, 123456780},  {123456789, 6, 123456789}, {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 7},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 100000000}, {123456789, 0, 120000000}, {123456789, 1, 123000000},
                 {123456789, 2, 123400000},  {123456789, 3, 123450000}, {123456789, 4, 123456000},
                 {123456789, 5, 123456700},  {123456789, 6, 123456780}, {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 8},
         {
                 {123456789, -10, 0},       {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},        {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},        {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 0},        {123456789, 0, 100000000}, {123456789, 1, 120000000},
                 {123456789, 2, 123000000}, {123456789, 3, 123400000}, {123456789, 4, 123450000},
                 {123456789, 5, 123456000}, {123456789, 6, 123456700}, {123456789, 7, 123456780},
                 {123456789, 8, 123456789}, {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 9},
         {
                 {123456789, -10, 0},       {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},        {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},        {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 0},        {123456789, 0, 0},         {123456789, 1, 100000000},
                 {123456789, 2, 120000000}, {123456789, 3, 123000000}, {123456789, 4, 123400000},
                 {123456789, 5, 123450000}, {123456789, 6, 123456000}, {123456789, 7, 123456700},
                 {123456789, 8, 123456780}, {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }}};

// test cases for truncate and floor function of decimal64
const static DecimalTestDataSet trunc_floor_decimal64_cases = {
        {{10, 0},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 1000000000},
          {1234567891, -8, 1200000000}, {1234567891, -7, 1230000000}, {1234567891, -6, 1234000000},
          {1234567891, -5, 1234500000}, {1234567891, -4, 1234560000}, {1234567891, -3, 1234567000},
          {1234567891, -2, 1234567800}, {1234567891, -1, 1234567890}, {1234567891, 0, 1234567891},
          {1234567891, 1, 1234567891},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{10, 1},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 0},
          {1234567891, -8, 1000000000}, {1234567891, -7, 1200000000}, {1234567891, -6, 1230000000},
          {1234567891, -5, 1234000000}, {1234567891, -4, 1234500000}, {1234567891, -3, 1234560000},
          {1234567891, -2, 1234567000}, {1234567891, -1, 1234567800}, {1234567891, 0, 1234567890},
          {1234567891, 1, 1234567891},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}

         }},
        {{10, 2},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 0},
          {1234567891, -8, 0},          {1234567891, -7, 1000000000}, {1234567891, -6, 1200000000},
          {1234567891, -5, 1230000000}, {1234567891, -4, 1234000000}, {1234567891, -3, 1234500000},
          {1234567891, -2, 1234560000}, {1234567891, -1, 1234567000}, {1234567891, 0, 1234567800},
          {1234567891, 1, 1234567890},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{10, 9},
         {{1234567891, -11, 0},         {1234567891, -10, 0},        {1234567891, -9, 0},
          {1234567891, -8, 0},          {1234567891, -7, 0},         {1234567891, -6, 0},
          {1234567891, -5, 0},          {1234567891, -4, 0},         {1234567891, -3, 0},
          {1234567891, -2, 0},          {1234567891, -1, 0},         {1234567891, 0, 1000000000},
          {1234567891, 1, 1200000000},  {1234567891, 2, 1230000000}, {1234567891, 3, 1234000000},
          {1234567891, 4, 1234500000},  {1234567891, 5, 1234560000}, {1234567891, 6, 1234567000},
          {1234567891, 7, 1234567800},  {1234567891, 8, 1234567890}, {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{18, 0},
         {{123456789123456789, -19, 0},
          {123456789123456789, -18, 0},
          {123456789123456789, -17, 100000000000000000},
          {123456789123456789, -16, 120000000000000000},
          {123456789123456789, -15, 123000000000000000},
          {123456789123456789, -14, 123400000000000000},
          {123456789123456789, -13, 123450000000000000},
          {123456789123456789, -12, 123456000000000000},
          {123456789123456789, -11, 123456700000000000},
          {123456789123456789, -10, 123456780000000000},
          {123456789123456789, -9, 123456789000000000},
          {123456789123456789, -8, 123456789100000000},
          {123456789123456789, -7, 123456789120000000},
          {123456789123456789, -6, 123456789123000000},
          {123456789123456789, -5, 123456789123400000},
          {123456789123456789, -4, 123456789123450000},
          {123456789123456789, -3, 123456789123456000},
          {123456789123456789, -2, 123456789123456700},
          {123456789123456789, -1, 123456789123456780},
          {123456789123456789, 0, 123456789123456789},
          {123456789123456789, 1, 123456789123456789},
          {123456789123456789, 2, 123456789123456789},
          {123456789123456789, 3, 123456789123456789},
          {123456789123456789, 4, 123456789123456789},
          {123456789123456789, 5, 123456789123456789},
          {123456789123456789, 6, 123456789123456789},
          {123456789123456789, 7, 123456789123456789},
          {123456789123456789, 8, 123456789123456789},
          {123456789123456789, 18, 123456789123456789}}},
        {{18, 18},
         {{123456789123456789, -1, 0},
          {123456789123456789, 0, 0},
          {123456789123456789, 1, 100000000000000000},
          {123456789123456789, 2, 120000000000000000},
          {123456789123456789, 3, 123000000000000000},
          {123456789123456789, 4, 123400000000000000},
          {123456789123456789, 5, 123450000000000000},
          {123456789123456789, 6, 123456000000000000},
          {123456789123456789, 7, 123456700000000000},
          {123456789123456789, 8, 123456780000000000},
          {123456789123456789, 9, 123456789000000000},
          {123456789123456789, 10, 123456789100000000},
          {123456789123456789, 11, 123456789120000000},
          {123456789123456789, 12, 123456789123000000},
          {123456789123456789, 13, 123456789123400000},
          {123456789123456789, 14, 123456789123450000},
          {123456789123456789, 15, 123456789123456000},
          {123456789123456789, 16, 123456789123456700},
          {123456789123456789, 17, 123456789123456780},
          {123456789123456789, 18, 123456789123456789},
          {123456789123456789, 19, 123456789123456789},
          {123456789123456789, 20, 123456789123456789},
          {123456789123456789, 21, 123456789123456789},
          {123456789123456789, 22, 123456789123456789},
          {123456789123456789, 23, 123456789123456789},
          {123456789123456789, 24, 123456789123456789},
          {123456789123456789, 25, 123456789123456789},
          {123456789123456789, 26, 123456789123456789}}}};

// test cases for ceil function of decimal32
const static DecimalTestDataSet ceil_decimal32_cases = {
        {{1, 0},
         {
                 {1, -10, 0},      {1, -9, 1000000000}, {1, -8, 100000000}, {1, -7, 10000000},
                 {1, -6, 1000000}, {1, -5, 100000},     {1, -4, 10000},     {1, -3, 1000},
                 {1, -2, 100},     {1, -1, 10},         {1, 0, 1},          {1, 1, 1},
                 {1, 2, 1},        {1, 3, 1},           {1, 4, 1},          {1, 5, 1},
                 {1, 6, 1},        {1, 7, 1},           {1, 8, 1},          {1, 9, 1},
                 {1, 10, 1},
         }},
        {{1, 1},
         {
                 {1, -10, 0},       {1, -9, 0},       {1, -8, 1000000000}, {1, -7, 100000000},
                 {1, -6, 10000000}, {1, -5, 1000000}, {1, -4, 100000},     {1, -3, 10000},
                 {1, -2, 1000},     {1, -1, 100},     {1, 0, 10},          {1, 1, 1},
                 {1, 2, 1},         {1, 3, 1},        {1, 4, 1},           {1, 5, 1},
                 {1, 6, 1},         {1, 7, 1},        {1, 8, 1},           {1, 9, 1},
                 {1, 10, 1},
         }},
        {{2, 0},
         {
                 {12, -4, 10000},
                 {12, -3, 1000},
                 {12, -2, 100},
                 {12, -1, 20},
                 {12, 0, 12},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 1},
         {
                 {12, -4, 100000},
                 {12, -3, 10000},
                 {12, -2, 1000},
                 {12, -1, 100},
                 {12, 0, 20},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 2},
         {
                 {12, -4, 1000000},
                 {12, -3, 100000},
                 {12, -2, 10000},
                 {12, -1, 1000},
                 {12, 0, 100},
                 {12, 1, 20},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{9, 0},
         {
                 {123456789, -10, 0},        {123456789, -9, 1000000000},
                 {123456789, -8, 200000000}, {123456789, -7, 130000000},
                 {123456789, -6, 124000000}, {123456789, -5, 123500000},
                 {123456789, -4, 123460000}, {123456789, -3, 123457000},
                 {123456789, -2, 123456800}, {123456789, -1, 123456790},
                 {123456789, 0, 123456789},  {123456789, 1, 123456789},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},
                 {123456789, 4, 123456789},  {123456789, 5, 123456789},
                 {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 1},
         {
                 {123456789, -10, 0},         {123456789, -9, 0},
                 {123456789, -8, 1000000000}, {123456789, -7, 200000000},
                 {123456789, -6, 130000000},  {123456789, -5, 124000000},
                 {123456789, -4, 123500000},  {123456789, -3, 123460000},
                 {123456789, -2, 123457000},  {123456789, -1, 123456800},
                 {123456789, 0, 123456790},   {123456789, 1, 123456789},
                 {123456789, 2, 123456789},   {123456789, 3, 123456789},
                 {123456789, 4, 123456789},   {123456789, 5, 123456789},
                 {123456789, 6, 123456789},   {123456789, 7, 123456789},
                 {123456789, 8, 123456789},   {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 2},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},
                 {123456789, -8, 0},         {123456789, -7, 1000000000},
                 {123456789, -6, 200000000}, {123456789, -5, 130000000},
                 {123456789, -4, 124000000}, {123456789, -3, 123500000},
                 {123456789, -2, 123460000}, {123456789, -1, 123457000},
                 {123456789, 0, 123456800},  {123456789, 1, 123456790},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},
                 {123456789, 4, 123456789},  {123456789, 5, 123456789},
                 {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 3},
         {
                 {123456789, -10, 0},         {123456789, -9, 0},
                 {123456789, -8, 0},          {123456789, -7, 0},
                 {123456789, -6, 1000000000}, {123456789, -5, 200000000},
                 {123456789, -4, 130000000},  {123456789, -3, 124000000},
                 {123456789, -2, 123500000},  {123456789, -1, 123460000},
                 {123456789, 0, 123457000},   {123456789, 1, 123456800},
                 {123456789, 2, 123456790},   {123456789, 3, 123456789},
                 {123456789, 4, 123456789},   {123456789, 5, 123456789},
                 {123456789, 6, 123456789},   {123456789, 7, 123456789},
                 {123456789, 8, 123456789},   {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 4},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},
                 {123456789, -8, 0},         {123456789, -7, 0},
                 {123456789, -6, 0},         {123456789, -5, 1000000000},
                 {123456789, -4, 200000000}, {123456789, -3, 130000000},
                 {123456789, -2, 124000000}, {123456789, -1, 123500000},
                 {123456789, 0, 123460000},  {123456789, 1, 123457000},
                 {123456789, 2, 123456800},  {123456789, 3, 123456790},
                 {123456789, 4, 123456789},  {123456789, 5, 123456789},
                 {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 5},
         {
                 {123456789, -10, 0},         {123456789, -9, 0},
                 {123456789, -8, 0},          {123456789, -7, 0},
                 {123456789, -6, 0},          {123456789, -5, 0},
                 {123456789, -4, 1000000000}, {123456789, -3, 200000000},
                 {123456789, -2, 130000000},  {123456789, -1, 124000000},
                 {123456789, 0, 123500000},   {123456789, 1, 123460000},
                 {123456789, 2, 123457000},   {123456789, 3, 123456800},
                 {123456789, 4, 123456790},   {123456789, 5, 123456789},
                 {123456789, 6, 123456789},   {123456789, 7, 123456789},
                 {123456789, 8, 123456789},   {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 6},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},
                 {123456789, -8, 0},         {123456789, -7, 0},
                 {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 1000000000},
                 {123456789, -2, 200000000}, {123456789, -1, 130000000},
                 {123456789, 0, 124000000},  {123456789, 1, 123500000},
                 {123456789, 2, 123460000},  {123456789, 3, 123457000},
                 {123456789, 4, 123456800},  {123456789, 5, 123456790},
                 {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},
                 {123456789, 10, 123456789},
         }},
        {{9, 7},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 0},        {123456789, -2, 1000000000},
                 {123456789, -1, 200000000}, {123456789, 0, 130000000}, {123456789, 1, 124000000},
                 {123456789, 2, 123500000},  {123456789, 3, 123460000}, {123456789, 4, 123457000},
                 {123456789, 5, 123456800},  {123456789, 6, 123456790}, {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 8},
         {
                 {123456789, -10, 0},         {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},          {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},          {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 1000000000}, {123456789, 0, 200000000}, {123456789, 1, 130000000},
                 {123456789, 2, 124000000},   {123456789, 3, 123500000}, {123456789, 4, 123460000},
                 {123456789, 5, 123457000},   {123456789, 6, 123456800}, {123456789, 7, 123456790},
                 {123456789, 8, 123456789},   {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 9},
         {
                 {123456789, -10, 0},       {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},        {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 0},        {123456789, -3, 0},         {123456789, -2, 0},
                 {123456789, -1, 0},        {123456789, 0, 1000000000}, {123456789, 1, 200000000},
                 {123456789, 2, 130000000}, {123456789, 3, 124000000},  {123456789, 4, 123500000},
                 {123456789, 5, 123460000}, {123456789, 6, 123457000},  {123456789, 7, 123456800},
                 {123456789, 8, 123456790}, {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }}};

// test cases for ceil function of decimal64
const static DecimalTestDataSet ceil_decimal64_cases = {
        {{10, 0}, {{1234567891, -11, 100000000000}, {1234567891, -10, 10000000000},
                   {1234567891, -9, 2000000000},    {1234567891, -8, 1300000000},
                   {1234567891, -7, 1240000000},    {1234567891, -6, 1235000000},
                   {1234567891, -5, 1234600000},    {1234567891, -4, 1234570000},
                   {1234567891, -3, 1234568000},    {1234567891, -2, 1234567900},
                   {1234567891, -1, 1234567900},    {1234567891, 0, 1234567891},
                   {1234567891, 1, 1234567891},     {1234567891, 2, 1234567891},
                   {1234567891, 3, 1234567891},     {1234567891, 4, 1234567891},
                   {1234567891, 5, 1234567891},     {1234567891, 6, 1234567891},
                   {1234567891, 7, 1234567891},     {1234567891, 8, 1234567891},
                   {1234567891, 9, 1234567891},     {1234567891, 10, 1234567891},
                   {1234567891, 11, 1234567891}}},
        {{10, 1}, {{1234567891, -11, 1000000000000}, {1234567891, -10, 100000000000},
                   {1234567891, -9, 10000000000},    {1234567891, -8, 2000000000},
                   {1234567891, -7, 1300000000},     {1234567891, -6, 1240000000},
                   {1234567891, -5, 1235000000},     {1234567891, -4, 1234600000},
                   {1234567891, -3, 1234570000},     {1234567891, -2, 1234568000},
                   {1234567891, -1, 1234567900},     {1234567891, 0, 1234567900},
                   {1234567891, 1, 1234567891},      {1234567891, 2, 1234567891},
                   {1234567891, 3, 1234567891},      {1234567891, 4, 1234567891},
                   {1234567891, 5, 1234567891},      {1234567891, 6, 1234567891},
                   {1234567891, 7, 1234567891},      {1234567891, 8, 1234567891},
                   {1234567891, 9, 1234567891},      {1234567891, 10, 1234567891},
                   {1234567891, 11, 1234567891}}},
        {{10, 2}, {{1234567891, -11, 10000000000000}, {1234567891, -10, 1000000000000},
                   {1234567891, -9, 100000000000},    {1234567891, -8, 10000000000},
                   {1234567891, -7, 2000000000},      {1234567891, -6, 1300000000},
                   {1234567891, -5, 1240000000},      {1234567891, -4, 1235000000},
                   {1234567891, -3, 1234600000},      {1234567891, -2, 1234570000},
                   {1234567891, -1, 1234568000},      {1234567891, 0, 1234567900},
                   {1234567891, 1, 1234567900},       {1234567891, 2, 1234567891},
                   {1234567891, 3, 1234567891},       {1234567891, 4, 1234567891},
                   {1234567891, 5, 1234567891},       {1234567891, 6, 1234567891},
                   {1234567891, 7, 1234567891},       {1234567891, 8, 1234567891},
                   {1234567891, 9, 1234567891},       {1234567891, 10, 1234567891},
                   {1234567891, 11, 1234567891}}},
        {{10, 9},
         {{1234567891, -11, 0},
          {1234567891, -10, 0},
          {1234567891, -9, 1000000000000000000},
          {1234567891, -8, 100000000000000000},
          {1234567891, -7, 10000000000000000},
          {1234567891, -6, 1000000000000000},
          {1234567891, -5, 100000000000000},
          {1234567891, -4, 10000000000000},
          {1234567891, -3, 1000000000000},
          {1234567891, -2, 100000000000},
          {1234567891, -1, 10000000000},
          {1234567891, 0, 2000000000},
          {1234567891, 1, 1300000000},
          {1234567891, 2, 1240000000},
          {1234567891, 3, 1235000000},
          {1234567891, 4, 1234600000},
          {1234567891, 5, 1234570000},
          {1234567891, 6, 1234568000},
          {1234567891, 7, 1234567900},
          {1234567891, 8, 1234567900},
          {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891},
          {1234567891, 11, 1234567891}}},
        {{18, 0},
         {{123456789123456789, -19, 0},
          {123456789123456789, -18, 1000000000000000000},
          {123456789123456789, -17, 200000000000000000},
          {123456789123456789, -16, 130000000000000000},
          {123456789123456789, -15, 124000000000000000},
          {123456789123456789, -14, 123500000000000000},
          {123456789123456789, -13, 123460000000000000},
          {123456789123456789, -12, 123457000000000000},
          {123456789123456789, -11, 123456800000000000},
          {123456789123456789, -10, 123456790000000000},
          {123456789123456789, -9, 123456790000000000},
          {123456789123456789, -8, 123456789200000000},
          {123456789123456789, -7, 123456789130000000},
          {123456789123456789, -6, 123456789124000000},
          {123456789123456789, -5, 123456789123500000},
          {123456789123456789, -4, 123456789123460000},
          {123456789123456789, -3, 123456789123457000},
          {123456789123456789, -2, 123456789123456800},
          {123456789123456789, -1, 123456789123456790},
          {123456789123456789, 0, 123456789123456789},
          {123456789123456789, 1, 123456789123456789},
          {123456789123456789, 2, 123456789123456789},
          {123456789123456789, 3, 123456789123456789},
          {123456789123456789, 4, 123456789123456789},
          {123456789123456789, 5, 123456789123456789},
          {123456789123456789, 6, 123456789123456789},
          {123456789123456789, 7, 123456789123456789},
          {123456789123456789, 8, 123456789123456789},
          {123456789123456789, 18, 123456789123456789}}},
        {{18, 18},
         {{123456789123456789, -1, 0},
          {123456789123456789, 0, 1000000000000000000},
          {123456789123456789, 1, 200000000000000000},
          {123456789123456789, 2, 130000000000000000},
          {123456789123456789, 3, 124000000000000000},
          {123456789123456789, 4, 123500000000000000},
          {123456789123456789, 5, 123460000000000000},
          {123456789123456789, 6, 123457000000000000},
          {123456789123456789, 7, 123456800000000000},
          {123456789123456789, 8, 123456790000000000},
          {123456789123456789, 9, 123456790000000000},
          {123456789123456789, 10, 123456789200000000},
          {123456789123456789, 11, 123456789130000000},
          {123456789123456789, 12, 123456789124000000},
          {123456789123456789, 13, 123456789123500000},
          {123456789123456789, 14, 123456789123460000},
          {123456789123456789, 15, 123456789123457000},
          {123456789123456789, 16, 123456789123456800},
          {123456789123456789, 17, 123456789123456790},
          {123456789123456789, 18, 123456789123456789},
          {123456789123456789, 19, 123456789123456789},
          {123456789123456789, 20, 123456789123456789},
          {123456789123456789, 21, 123456789123456789},
          {123456789123456789, 22, 123456789123456789},
          {123456789123456789, 23, 123456789123456789},
          {123456789123456789, 24, 123456789123456789},
          {123456789123456789, 25, 123456789123456789},
          {123456789123456789, 26, 123456789123456789}}}};

// test cases for round and round_bankers function of decimal32
const static DecimalTestDataSet round_decimal32_cases = {
        {{1, 0},
         {
                 {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0}, {1, -5, 0},
                 {1, -4, 0},  {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 1},  {1, 1, 1},
                 {1, 2, 1},   {1, 3, 1},  {1, 4, 1},  {1, 5, 1},  {1, 6, 1},  {1, 7, 1},
                 {1, 8, 1},   {1, 9, 1},  {1, 10, 1},
         }},
        {{1, 1},
         {
                 {1, -10, 0}, {1, -9, 0}, {1, -8, 0}, {1, -7, 0}, {1, -6, 0}, {1, -5, 0},
                 {1, -4, 0},  {1, -3, 0}, {1, -2, 0}, {1, -1, 0}, {1, 0, 0},  {1, 1, 1},
                 {1, 2, 1},   {1, 3, 1},  {1, 4, 1},  {1, 5, 1},  {1, 6, 1},  {1, 7, 1},
                 {1, 8, 1},   {1, 9, 1},  {1, 10, 1},
         }},
        {{2, 0},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 10},
                 {12, 0, 12},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 1},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 0},
                 {12, 0, 10},
                 {12, 1, 12},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{2, 2},
         {
                 {12, -4, 0},
                 {12, -3, 0},
                 {12, -2, 0},
                 {12, -1, 0},
                 {12, 0, 0},
                 {12, 1, 10},
                 {12, 2, 12},
                 {12, 3, 12},
                 {12, 4, 12},
         }},
        {{9, 0},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 100000000},
                 {123456789, -7, 120000000}, {123456789, -6, 123000000}, {123456789, -5, 123500000},
                 {123456789, -4, 123460000}, {123456789, -3, 123457000}, {123456789, -2, 123456800},
                 {123456789, -1, 123456790}, {123456789, 0, 123456789},  {123456789, 1, 123456789},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 1},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 100000000}, {123456789, -6, 120000000}, {123456789, -5, 123000000},
                 {123456789, -4, 123500000}, {123456789, -3, 123460000}, {123456789, -2, 123457000},
                 {123456789, -1, 123456800}, {123456789, 0, 123456790},  {123456789, 1, 123456789},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 2},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 100000000}, {123456789, -5, 120000000},
                 {123456789, -4, 123000000}, {123456789, -3, 123500000}, {123456789, -2, 123460000},
                 {123456789, -1, 123457000}, {123456789, 0, 123456800},  {123456789, 1, 123456790},
                 {123456789, 2, 123456789},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 3},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 100000000},
                 {123456789, -4, 120000000}, {123456789, -3, 123000000}, {123456789, -2, 123500000},
                 {123456789, -1, 123460000}, {123456789, 0, 123457000},  {123456789, 1, 123456800},
                 {123456789, 2, 123456790},  {123456789, 3, 123456789},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 4},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 100000000}, {123456789, -3, 120000000}, {123456789, -2, 123000000},
                 {123456789, -1, 123500000}, {123456789, 0, 123460000},  {123456789, 1, 123457000},
                 {123456789, 2, 123456800},  {123456789, 3, 123456790},  {123456789, 4, 123456789},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 5},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},         {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},         {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 100000000}, {123456789, -2, 120000000},
                 {123456789, -1, 123000000}, {123456789, 0, 123500000},  {123456789, 1, 123460000},
                 {123456789, 2, 123457000},  {123456789, 3, 123456800},  {123456789, 4, 123456790},
                 {123456789, 5, 123456789},  {123456789, 6, 123456789},  {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789},  {123456789, 10, 123456789},
         }},
        {{9, 6},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 0},        {123456789, -2, 100000000},
                 {123456789, -1, 120000000}, {123456789, 0, 123000000}, {123456789, 1, 123500000},
                 {123456789, 2, 123460000},  {123456789, 3, 123457000}, {123456789, 4, 123456800},
                 {123456789, 5, 123456790},  {123456789, 6, 123456789}, {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 7},
         {
                 {123456789, -10, 0},        {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},         {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},         {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 100000000}, {123456789, 0, 120000000}, {123456789, 1, 123000000},
                 {123456789, 2, 123500000},  {123456789, 3, 123460000}, {123456789, 4, 123457000},
                 {123456789, 5, 123456800},  {123456789, 6, 123456790}, {123456789, 7, 123456789},
                 {123456789, 8, 123456789},  {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 8},
         {
                 {123456789, -10, 0},       {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},        {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},        {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 0},        {123456789, 0, 100000000}, {123456789, 1, 120000000},
                 {123456789, 2, 123000000}, {123456789, 3, 123500000}, {123456789, 4, 123460000},
                 {123456789, 5, 123457000}, {123456789, 6, 123456800}, {123456789, 7, 123456790},
                 {123456789, 8, 123456789}, {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }},
        {{9, 9},
         {
                 {123456789, -10, 0},       {123456789, -9, 0},        {123456789, -8, 0},
                 {123456789, -7, 0},        {123456789, -6, 0},        {123456789, -5, 0},
                 {123456789, -4, 0},        {123456789, -3, 0},        {123456789, -2, 0},
                 {123456789, -1, 0},        {123456789, 0, 0},         {123456789, 1, 100000000},
                 {123456789, 2, 120000000}, {123456789, 3, 123000000}, {123456789, 4, 123500000},
                 {123456789, 5, 123460000}, {123456789, 6, 123457000}, {123456789, 7, 123456800},
                 {123456789, 8, 123456790}, {123456789, 9, 123456789}, {123456789, 10, 123456789},
         }}};

// test cases for round and round_bankers function of decimal64
const static DecimalTestDataSet round_decimal64_cases = {
        {{10, 0},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 1000000000},
          {1234567891, -8, 1200000000}, {1234567891, -7, 1230000000}, {1234567891, -6, 1235000000},
          {1234567891, -5, 1234600000}, {1234567891, -4, 1234570000}, {1234567891, -3, 1234568000},
          {1234567891, -2, 1234567900}, {1234567891, -1, 1234567890}, {1234567891, 0, 1234567891},
          {1234567891, 1, 1234567891},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{10, 1},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 0},
          {1234567891, -8, 1000000000}, {1234567891, -7, 1200000000}, {1234567891, -6, 1230000000},
          {1234567891, -5, 1235000000}, {1234567891, -4, 1234600000}, {1234567891, -3, 1234570000},
          {1234567891, -2, 1234568000}, {1234567891, -1, 1234567900}, {1234567891, 0, 1234567890},
          {1234567891, 1, 1234567891},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}

         }},
        {{10, 2},
         {{1234567891, -11, 0},         {1234567891, -10, 0},         {1234567891, -9, 0},
          {1234567891, -8, 0},          {1234567891, -7, 1000000000}, {1234567891, -6, 1200000000},
          {1234567891, -5, 1230000000}, {1234567891, -4, 1235000000}, {1234567891, -3, 1234600000},
          {1234567891, -2, 1234570000}, {1234567891, -1, 1234568000}, {1234567891, 0, 1234567900},
          {1234567891, 1, 1234567890},  {1234567891, 2, 1234567891},  {1234567891, 3, 1234567891},
          {1234567891, 4, 1234567891},  {1234567891, 5, 1234567891},  {1234567891, 6, 1234567891},
          {1234567891, 7, 1234567891},  {1234567891, 8, 1234567891},  {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{10, 9},
         {{1234567891, -11, 0},         {1234567891, -10, 0},        {1234567891, -9, 0},
          {1234567891, -8, 0},          {1234567891, -7, 0},         {1234567891, -6, 0},
          {1234567891, -5, 0},          {1234567891, -4, 0},         {1234567891, -3, 0},
          {1234567891, -2, 0},          {1234567891, -1, 0},         {1234567891, 0, 1000000000},
          {1234567891, 1, 1200000000},  {1234567891, 2, 1230000000}, {1234567891, 3, 1235000000},
          {1234567891, 4, 1234600000},  {1234567891, 5, 1234570000}, {1234567891, 6, 1234568000},
          {1234567891, 7, 1234567900},  {1234567891, 8, 1234567890}, {1234567891, 9, 1234567891},
          {1234567891, 10, 1234567891}, {1234567891, 11, 1234567891}}},
        {{18, 0},
         {{123456789123456789, -19, 0},
          {123456789123456789, -18, 0},
          {123456789123456789, -17, 100000000000000000},
          {123456789123456789, -16, 120000000000000000},
          {123456789123456789, -15, 123000000000000000},
          {123456789123456789, -14, 123500000000000000},
          {123456789123456789, -13, 123460000000000000},
          {123456789123456789, -12, 123457000000000000},
          {123456789123456789, -11, 123456800000000000},
          {123456789123456789, -10, 123456790000000000},
          {123456789123456789, -9, 123456789000000000},
          {123456789123456789, -8, 123456789100000000},
          {123456789123456789, -7, 123456789120000000},
          {123456789123456789, -6, 123456789123000000},
          {123456789123456789, -5, 123456789123500000},
          {123456789123456789, -4, 123456789123460000},
          {123456789123456789, -3, 123456789123457000},
          {123456789123456789, -2, 123456789123456800},
          {123456789123456789, -1, 123456789123456790},
          {123456789123456789, 0, 123456789123456789},
          {123456789123456789, 1, 123456789123456789},
          {123456789123456789, 2, 123456789123456789},
          {123456789123456789, 3, 123456789123456789},
          {123456789123456789, 4, 123456789123456789},
          {123456789123456789, 5, 123456789123456789},
          {123456789123456789, 6, 123456789123456789},
          {123456789123456789, 7, 123456789123456789},
          {123456789123456789, 8, 123456789123456789},
          {123456789123456789, 18, 123456789123456789}}},
        {{18, 18},
         {{123456789123456789, -1, 0},
          {123456789123456789, 0, 0},
          {123456789123456789, 1, 100000000000000000},
          {123456789123456789, 2, 120000000000000000},
          {123456789123456789, 3, 123000000000000000},
          {123456789123456789, 4, 123500000000000000},
          {123456789123456789, 5, 123460000000000000},
          {123456789123456789, 6, 123457000000000000},
          {123456789123456789, 7, 123456800000000000},
          {123456789123456789, 8, 123456790000000000},
          {123456789123456789, 9, 123456789000000000},
          {123456789123456789, 10, 123456789100000000},
          {123456789123456789, 11, 123456789120000000},
          {123456789123456789, 12, 123456789123000000},
          {123456789123456789, 13, 123456789123500000},
          {123456789123456789, 14, 123456789123460000},
          {123456789123456789, 15, 123456789123457000},
          {123456789123456789, 16, 123456789123456800},
          {123456789123456789, 17, 123456789123456790},
          {123456789123456789, 18, 123456789123456789},
          {123456789123456789, 19, 123456789123456789},
          {123456789123456789, 20, 123456789123456789},
          {123456789123456789, 21, 123456789123456789},
          {123456789123456789, 22, 123456789123456789},
          {123456789123456789, 23, 123456789123456789},
          {123456789123456789, 24, 123456789123456789},
          {123456789123456789, 25, 123456789123456789},
          {123456789123456789, 26, 123456789123456789}}}};

// test cases for truncate function of float32
FloatTestDataSet trunc_float32_cases = {
        {10.0, 1, 10.0}, {10.0, 0, 10.0}, {-124.3867, -2, -100}, {123.123456, 4, 123.123400}};

// test cases for truncate function of float64
FloatTestDataSet trunc_float64_cases = {{10.0, 1, 10.0},
                                        {10.0, 0, 10.0},
                                        {-124.3867, -2, -100},
                                        {123.123456, 1, 123.100000},
                                        {123456789.123456, 4, 123456789.123400}};

// test cases for floor function of float32
FloatTestDataSet floor_float32_cases = {
        {10.1234, 1, 10.1}, {10.3, 0, 10.0}, {-124.3867, -2, -200}, {123.123456, 4, 123.123400}};

// test cases for floor function of float64
FloatTestDataSet floor_float64_cases = {{10.1234, 1, 10.1},
                                        {10.3, 0, 10.0},
                                        {-124.3867, -2, -200},
                                        {123.123456, 4, 123.123400},
                                        {123456789.123456, 5, 123456789.123450}};

// test cases for ceil function of float32
FloatTestDataSet ceil_float32_cases = {
        {10.1234, 1, 10.2}, {10.3, 0, 11}, {-124.3867, -2, -100}, {123.123456, 4, 123.123500}};

// test cases for ceil function of float64
FloatTestDataSet ceil_float64_cases = {{10.1234, 1, 10.2},
                                       {10.3, 0, 11},
                                       {-124.3867, -2, -100},
                                       {123.123456, 4, 123.123500},
                                       {123456789.123456, 4, 123456789.123500}};

// test cases for round function of float32
FloatTestDataSet round_float32_cases = {{2.5, 0, 3.0},
                                        {10.1234, 1, 10.1},
                                        {10.3, 0, 10},
                                        {-124.3867, -2, -100},
                                        {123.123456, 4, 123.123500}};

// test cases for round function of float64
FloatTestDataSet round_float64_cases = {{2.5, 0, 3.0},
                                        {10.1234, 1, 10.1},
                                        {10.3, 0, 10},
                                        {-124.3867, -2, -100},
                                        {123.123456, 4, 123.123500},
                                        {123456789.123456, 4, 123456789.123500}};

// test cases for round_bankers function of float32
FloatTestDataSet round_bankers_float32_cases = {{2.5, 0, 2.0},
                                                {10.1234, 1, 10.1},
                                                {10.3, 0, 10},
                                                {-124.3867, -2, -100},
                                                {123.123456, 4, 123.123500}};

// test cases for round_bankers function of float64
FloatTestDataSet round_bankers_float64_cases = {{2.5, 0, 2.0},
                                                {10.1234, 1, 10.1},
                                                {10.3, 0, 10},
                                                {-124.3867, -2, -100},
                                                {123.123456, 4, 123.123500},
                                                {123456789.123456, 4, 123456789.123500}};

template <typename FuncType, typename DecimalType>
static void decimal_checker(const DecimalTestDataSet& round_test_cases, bool decimal_col_is_const) {
    static_assert(IsDecimalNumber<DecimalType>);
    auto func = std::dynamic_pointer_cast<FuncType>(FuncType::create());
    FunctionContext* context = nullptr;

    for (const auto& test_case : round_test_cases) {
        Block block;
        size_t res_idx = 2;
        ColumnNumbers arguments = {0, 1, 2};
        const int precision = test_case.first.first;
        const int scale = test_case.first.second;
        const size_t input_rows_count = test_case.second.size();
        auto col_general = ColumnDecimal<DecimalType>::create(input_rows_count, scale);
        auto col_scale = ColumnInt32::create();
        auto col_res_expected = ColumnDecimal<DecimalType>::create(input_rows_count, scale);
        size_t rid = 0;

        for (const auto& test_date : test_case.second) {
            auto input = std::get<0>(test_date);
            auto scale_arg = std::get<1>(test_date);
            auto expectation = std::get<2>(test_date);
            col_general->get_element(rid) = DecimalType(input);
            col_scale->insert(scale_arg);
            col_res_expected->get_element(rid) = DecimalType(expectation);
            rid++;
        }

        if (decimal_col_is_const) {
            block.insert({ColumnConst::create(col_general->clone_resized(1), 1),
                          std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
                          "col_general_const"});
        } else {
            block.insert({col_general->clone(),
                          std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
                          "col_general"});
        }

        block.insert({col_scale->clone(), std::make_shared<DataTypeInt32>(), "col_scale"});
        block.insert({nullptr, std::make_shared<DataTypeDecimal<DecimalType>>(precision, scale),
                      "col_res"});

        auto status = func->execute_impl(context, block, arguments, res_idx, input_rows_count);
        auto col_res = assert_cast<const ColumnDecimal<DecimalType>&>(
                *(block.get_by_position(res_idx).column));
        EXPECT_TRUE(status.ok());

        for (size_t i = 0; i < input_rows_count; ++i) {
            auto res = col_res.get_element(i);
            auto res_expected = col_res_expected->get_element(i);
            EXPECT_EQ(res, res_expected)
                    << "function " << func->get_name() << " decimal_type "
                    << TypeName<DecimalType>().get() << " precision " << precision
                    << " input_scale " << scale << " input " << col_general->get_element(i)
                    << " scale_arg " << col_scale->get_element(i) << " decimal_col_is_const "
                    << decimal_col_is_const << " res " << res << " res_expected " << res_expected;
        }
    }
}

template <typename FuncType, typename FloatType>
static void float_checker(const FloatTestDataSet& round_test_cases, bool float_col_is_const) {
    static_assert(IsNumber<FloatType>);
    auto func = std::dynamic_pointer_cast<FuncType>(FuncType::create());
    FunctionContext* context = nullptr;

    for (const auto& test_case : round_test_cases) {
        auto col_general = ColumnVector<FloatType>::create(1);
        auto col_scale = ColumnInt32::create();
        auto col_res_expected = ColumnVector<FloatType>::create(1);
        size_t rid = 0;

        Block block;
        size_t res_idx = 2;
        ColumnNumbers arguments = {0, 1, 2};

        auto input = std::get<0>(test_case);
        auto scale_arg = std::get<1>(test_case);
        auto expectation = std::get<2>(test_case);
        col_general->get_element(rid) = FloatType(input);
        col_scale->insert(scale_arg);
        col_res_expected->get_element(rid) = FloatType(expectation);
        rid++;

        if (float_col_is_const) {
            block.insert({ColumnConst::create(col_general->clone_resized(1), 1),
                          std::make_shared<DataTypeNumber<FloatType>>(), "col_general_const"});
        } else {
            block.insert({col_general->clone(), std::make_shared<DataTypeNumber<FloatType>>(),
                          "col_general"});
        }

        block.insert({col_scale->clone(), std::make_shared<DataTypeInt32>(), "col_scale"});
        block.insert({nullptr, std::make_shared<DataTypeNumber<FloatType>>(), "col_res"});

        auto status = func->execute_impl(context, block, arguments, res_idx, 1);
        auto col_res = assert_cast<const ColumnVector<FloatType>&>(
                *(block.get_by_position(res_idx).column));
        EXPECT_TRUE(status.ok());

        auto res = col_res.get_element(0);
        auto res_expected = col_res_expected->get_element(0);
        EXPECT_EQ(res, res_expected)
                << "function " << func->get_name() << " float_type " << TypeName<FloatType>().get()
                << " input " << col_general->get_element(0) << " scale_arg "
                << col_scale->get_element(0) << " float_col_is_const " << float_col_is_const
                << " res " << res << " res_expected " << res_expected;
    }
}

/// tests for func(Column, Column) with decimal input
TEST(RoundFunctionTest, normal_decimal) {
    decimal_checker<DecimalTruncateFunction, Decimal32>(trunc_floor_decimal32_cases, false);
    decimal_checker<DecimalTruncateFunction, Decimal64>(trunc_floor_decimal64_cases, false);

    decimal_checker<DecimalFloorFunction, Decimal32>(trunc_floor_decimal32_cases, false);
    decimal_checker<DecimalFloorFunction, Decimal64>(trunc_floor_decimal64_cases, false);

    decimal_checker<DecimalCeilFunction, Decimal32>(ceil_decimal32_cases, false);
    decimal_checker<DecimalCeilFunction, Decimal64>(ceil_decimal64_cases, false);

    decimal_checker<DecimalRoundFunction, Decimal32>(round_decimal32_cases, false);
    decimal_checker<DecimalRoundFunction, Decimal64>(round_decimal64_cases, false);

    decimal_checker<DecimalRoundBankersFunction, Decimal32>(round_decimal32_cases, false);
    decimal_checker<DecimalRoundBankersFunction, Decimal64>(round_decimal64_cases, false);
}

/// tests for func(ColumnConst, Column) with decimal input
TEST(RoundFunctionTest, normal_decimal_const) {
    decimal_checker<DecimalTruncateFunction, Decimal32>(trunc_floor_decimal32_cases, true);
    decimal_checker<DecimalTruncateFunction, Decimal64>(trunc_floor_decimal64_cases, true);

    decimal_checker<DecimalFloorFunction, Decimal32>(trunc_floor_decimal32_cases, true);
    decimal_checker<DecimalFloorFunction, Decimal64>(trunc_floor_decimal64_cases, true);

    decimal_checker<DecimalCeilFunction, Decimal32>(ceil_decimal32_cases, true);
    decimal_checker<DecimalCeilFunction, Decimal64>(ceil_decimal64_cases, true);

    decimal_checker<DecimalRoundFunction, Decimal32>(round_decimal32_cases, true);
    decimal_checker<DecimalRoundFunction, Decimal64>(round_decimal64_cases, true);

    decimal_checker<DecimalRoundBankersFunction, Decimal32>(round_decimal32_cases, true);
    decimal_checker<DecimalRoundBankersFunction, Decimal64>(round_decimal64_cases, true);
}

/// tests for func(Column, Column) with float input
TEST(RoundFunctionTest, normal_float) {
    float_checker<FloatTruncateFunction, Float32>(trunc_float32_cases, false);
    float_checker<FloatTruncateFunction, Float64>(trunc_float64_cases, false);

    float_checker<FloatFloorFunction, Float32>(floor_float32_cases, false);
    float_checker<FloatFloorFunction, Float64>(floor_float64_cases, false);

    float_checker<FloatCeilFunction, Float32>(ceil_float32_cases, false);
    float_checker<FloatCeilFunction, Float64>(ceil_float64_cases, false);

    float_checker<FloatRoundFunction, Float32>(round_float32_cases, false);
    float_checker<FloatRoundFunction, Float64>(round_float64_cases, false);

    float_checker<FloatRoundBankersFunction, Float32>(round_bankers_float32_cases, false);
    float_checker<FloatRoundBankersFunction, Float64>(round_bankers_float64_cases, false);
}

/// tests for func(ColumnConst, Column) with float input
TEST(RoundFunctionTest, normal_float_const) {
    float_checker<FloatTruncateFunction, Float32>(trunc_float32_cases, true);
    float_checker<FloatTruncateFunction, Float64>(trunc_float64_cases, true);

    float_checker<FloatFloorFunction, Float32>(floor_float32_cases, true);
    float_checker<FloatFloorFunction, Float64>(floor_float64_cases, true);

    float_checker<FloatCeilFunction, Float32>(ceil_float32_cases, true);
    float_checker<FloatCeilFunction, Float64>(ceil_float64_cases, true);

    float_checker<FloatRoundFunction, Float32>(round_float32_cases, true);
    float_checker<FloatRoundFunction, Float64>(round_float64_cases, true);

    float_checker<FloatRoundBankersFunction, Float32>(round_bankers_float32_cases, true);
    float_checker<FloatRoundBankersFunction, Float64>(round_bankers_float64_cases, true);
}

} // namespace doris::vectorized
